package org.wisdom.ac.apis.assembler;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.stereotype.Component;
import org.wisdom.ac.domain.resource.entity.*;
import org.wisdom.ac.domain.resource.repository.*;
import org.wisdom.ac.dto.ResourceDto;
import org.wisdom.exception.BusinessException;

import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;

/**
 * 资源组装器
 *
 * @author 张智研
 * @date 2022/05/23 13:59
 **/
@Component
@RequiredArgsConstructor
public class ResourceAssembler {

    private final AppPageRepository appPageRepository;
    private final AppWidgetRepository appWidgetRepository;
    private final AppFacadeRepository appFacadeRepository;
    private final AppPageElementRepository appPageElementRepository;
    private final AppRepository appRepository;

    /**
     * 资源dto转换为应用实体
     *
     * @author 张智研
     * @date 2022/05/27 21:09
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.entity.AcApp
     */
    public AcApp resourceDtoToAppEntity(ResourceDto resourceDto) {
        return BeanUtil.copyProperties(resourceDto, AcApp.class);
    }

    /**
     * 资源dto转换为资源实体
     * 
     * @author 张智研
     * @date 2022/09/27 14:53
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.entity.AcResource
     */
    public AcResource resourceDtoToResourceEntity(ResourceDto resourceDto) {
        return BeanUtil.copyProperties(resourceDto, AcResource.class);
    }

    /**
     * 资源dto转换为应用服务实体
     *
     * @author 张智研
     * @date 2022/05/27 21:09
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.entity.AcAppFacade
     */
    public AcAppFacade resourceDtoToAppFacadeEntity(ResourceDto resourceDto) {
        return BeanUtil.copyProperties(resourceDto, AcAppFacade.class);
    }

    /**
     * 资源dto转换为应用页面实体
     *
     * @author 张智研
     * @date 2022/05/27 21:09
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.entity.AcAppFacade
     */
    public AcAppPage resourceDtoToAppPageEntity(ResourceDto resourceDto) {
        AcAppPage appPage = BeanUtil.copyProperties(resourceDto, AcAppPage.class);
        appPage.setAppPageFacades(this.getAppPageFacade(resourceDto));
        appPage.setAppPageWidgets(this.getAppPageWidget(resourceDto));
        appPage.setAppPageElements(this.getAppPageElement(resourceDto));
        return appPage;
    }

    /**
     * 资源dto转换为应用页面实体
     *
     * @author 张智研
     * @date 2022/09/16 14:33
     * @param resourceDtoList
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppPage>
     */
    public List<AcAppPage> resourceDtoToAppPageEntity(List<ResourceDto> resourceDtoList) {
        return resourceDtoList.stream().map(this::resourceDtoToAppPageEntity).collect(Collectors.toList());
    }

    /**
     * 资源dto转换为应用页面元素实体
     *
     * @author 张智研
     * @date 2023/04/23 10:02
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.resource.entity.AcAppPageElement
     */
    public AcAppPageElement resourceDtoToAppPageElementEntity(ResourceDto resourceDto) {
        AcAppPageElement appPageElement = BeanUtil.copyProperties(resourceDto, AcAppPageElement.class);
        appPageElement.setAppPageElementFacades(this.getAppPageElementFacade(resourceDto));
        return appPageElement;
    }

    /**
     * 资源dto转换为应用控件实体
     *
     * @author 张智研
     * @date 2022/05/27 21:09
     * @param resourceDto
     *            资源信息
     * @return org.wisdom.ac.domain.entity.AcAppFacade
     */
    public AcAppWidget resourceDtoToAppWidgetEntity(ResourceDto resourceDto) {
        AcAppWidget appWidget = BeanUtil.copyProperties(resourceDto, AcAppWidget.class);
        appWidget.setAppWidgetFacades(this.getAppWidgetFacade(resourceDto));
        return appWidget;
    }

    /**
     * 资源dto转换为应用控件实体
     *
     * @author 张智研
     * @date 2022/09/27 13:51
     * @param resourceDtoList
     *            资源信息列表
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppWidget>
     */
    public List<AcAppWidget> resourceDtoToAppWidgetEntity(List<ResourceDto> resourceDtoList) {
        return resourceDtoList.stream().map(this::resourceDtoToAppWidgetEntity).collect(Collectors.toList());
    }

    /**
     * 资源实体转换为dto
     *
     * @author 张智研
     * @date 2023/04/23 10:05
     * @param resource
     *            资源实体
     * @return org.wisdom.ac.dto.ResourceDto
     */
    public ResourceDto resourceEntityToDto(AcResource resource) {
        ResourceDto resourceDto = BeanUtil.copyProperties(resource, ResourceDto.class);
        if(resource instanceof AcAppPage) {
            AcAppPage appPage = (AcAppPage) resource;
            String[] facadeIds = new String[appPage.getAppPageFacades().size()];
            int n = 0;
            for(AcAppPageFacade appPageFacade : appPage.getAppPageFacades()) {
                facadeIds[n++] = appPageFacade.getAppFacadeId();
            }
            resourceDto.setFacadeIds(facadeIds);
            String[] elementIds = new String[appPage.getAppPageElements().size()];
            n = 0;
            for(AcAppPageElement appPageElement : appPage.getAppPageElements()) {
                elementIds[n++] = appPageElement.getId();
            }
            resourceDto.setElementIds(elementIds);
            String[] widgetIds = new String[appPage.getAppPageWidgets().size()];
            n = 0;
            for(AcAppPageWidget appPageWidget : appPage.getAppPageWidgets()) {
                widgetIds[n++] = appPageWidget.getAppWidgetId();
            }
            resourceDto.setWidgetIds(widgetIds);
        }else if(resource instanceof AcAppPageElement) {
            AcAppPageElement appPageElement = (AcAppPageElement) resource;
            String[] facadeIds = new String[appPageElement.getAppPageElementFacades().size()];
            int n = 0;
            for(AcAppPageElementFacade appPageElementFacade : appPageElement.getAppPageElementFacades()) {
                facadeIds[n++] = appPageElementFacade.getAppFacadeId();
            }
            resourceDto.setFacadeIds(facadeIds);
        }

        return resourceDto;
    }

    /**
     * 资源实体列表转换为dto列表
     *
     * @author 张智研
     * @date 2023/04/23 10:05
     * @param resourceList
     *            资源列表
     * @return java.util.List<org.wisdom.ac.dto.ResourceDto>
     */
    public List<ResourceDto> resourceEntityToDto(List<AcResource> resourceList) {
        return resourceList.stream().map(this::resourceEntityToDto).collect(Collectors.toList());
    }
    /**
     * 转换元素数组
     *
     * @author 张智研
     * @date 2022/06/06 14:58
     * @param resourceDto
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppPageFacade>
     */
    private List<AcAppPageElement> getAppPageElement(ResourceDto resourceDto) {
        String[] elementIds = resourceDto.getElementIds();
        List<AcAppPageElement> appPageElementList = new ArrayList<>();
        for (String elementId : elementIds) {
            Optional<AcAppPageElement> appPageElementOptional = this.appPageElementRepository.findById(elementId);
            if (!appPageElementOptional.isPresent()) {
                throw new BusinessException("元素{" + elementId + "}不存在!");
            }
            appPageElementList.add(appPageElementOptional.get());
        }
        return appPageElementList;
    }
    /**
     * 转换组件数组
     *
     * @author 张智研
     * @date 2022/06/06 14:58
     * @param resourceDto
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppPageFacade>
     */
    private List<AcAppPageWidget> getAppPageWidget(ResourceDto resourceDto) {
        String[] widgetIds = resourceDto.getWidgetIds();
        List<AcAppPageWidget> appPageWidgetList = new ArrayList<>();
        for (String widgetId : widgetIds) {
            boolean isExists = this.appWidgetRepository.existsById(widgetId);
            if (!isExists) {
                throw new BusinessException("组件{" + widgetId + "}不存在!");
            }
            AcAppPageWidget appPageWidget = new AcAppPageWidget();
            appPageWidget.setAppWidgetId(widgetId);
            appPageWidgetList.add(appPageWidget);
        }
        return appPageWidgetList;
    }

    /**
     * 转换接口数组
     *
     * @author 张智研
     * @date 2022/06/06 14:58
     * @param resourceDto
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppPageFacade>
     */
    private List<AcAppPageFacade> getAppPageFacade(ResourceDto resourceDto) {
        String[] facadeIds = resourceDto.getFacadeIds();
        List<AcAppPageFacade> appPageFacadeList = new ArrayList<>();
        for (String facadeId : facadeIds) {
            boolean isExists = this.appFacadeRepository.existsById(facadeId);
            if (!isExists) {
                throw new BusinessException("接口{" + facadeId + "}不存在!");
            }
            AcAppPageFacade appPageFacade = new AcAppPageFacade();
            appPageFacade.setAppFacadeId(facadeId);
            appPageFacadeList.add(appPageFacade);
        }
        return appPageFacadeList;
    }

    /**
     * 转换接口数组
     *
     * @author 张智研
     * @date 2022/06/06 14:58
     * @param resourceDto
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.entity.AcAppPageFacade>
     */
    private List<AcAppWidgetFacade> getAppWidgetFacade(ResourceDto resourceDto) {
        String[] facadeIds = resourceDto.getFacadeIds();
        List<AcAppWidgetFacade> appWidgetFacadeList = new ArrayList<>();
        for (String facadeId : facadeIds) {
            boolean isExists = this.appFacadeRepository.existsById(facadeId);
            if (!isExists) {
                throw new BusinessException("接口{" + facadeId + "}不存在!");
            }
            AcAppWidgetFacade acAppWidgetFacade = new AcAppWidgetFacade();
            acAppWidgetFacade.setAppFacadeId(facadeId);
            appWidgetFacadeList.add(acAppWidgetFacade);
        }
        return appWidgetFacadeList;
    }

    /**
     * 转换接口数组
     *
     * @author 张智研
     * @date 2023/04/23 10:07
     * @param resourceDto
     *            资源信息
     * @return java.util.List<org.wisdom.ac.domain.resource.entity.AcAppPageElementFacade>
     */
    private List<AcAppPageElementFacade> getAppPageElementFacade(ResourceDto resourceDto) {
        String[] facadeIds = resourceDto.getFacadeIds();
        List<AcAppPageElementFacade> appPageElementFacadeList = new ArrayList<>();
        for (String facadeId : facadeIds) {
            boolean isExists = this.appFacadeRepository.existsById(facadeId);
            if (!isExists) {
                throw new BusinessException("接口{" + facadeId + "}不存在!");
            }
            AcAppPageElementFacade appPageElementFacade = new AcAppPageElementFacade();
            appPageElementFacade.setAppFacadeId(facadeId);
            appPageElementFacadeList.add(appPageElementFacade);
        }
        return appPageElementFacadeList;
    }
}
